
package com.github.ybq.parallaxviewpager;

import com.github.ybq.parallaxviewpager.Interpolator.DecelerateInterpolator;
import com.github.ybq.parallaxviewpager.Interpolator.Interpolator;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;

/**
 * Author : ybq
 * Date :  15/8/15.
 */
public class ParallaxTransformer implements ParallaxViewPager.PageTransformer {
    /**
     * TAG
     */
    private static final String TAG = "ParallaxTransformer";
    /**
     * M mode
     */
    private Mode mMode;
    /**
     * M interpolator
     */
    private Interpolator mInterpolator = new DecelerateInterpolator();
    /**
     * M outset
     */
    private int mOutset;
    /**
     * M outset fraction
     */
    private float mOutsetFraction = 0.5f;

    /**
     * Parallax transformer
     */
    public ParallaxTransformer() {
    }

    /**
     * Gets mode *
     *
     * @return the mode
     */
    public Mode getMode() {
        return mMode;
    }

    /**
     * Sets mode *
     *
     * @param mode mode
     */
    public void setMode(Mode mode) {
        mMode = mode;
    }

    /**
     * Gets interpolator *
     *
     * @return the interpolator
     */
    public Interpolator getInterpolator() {
        return mInterpolator;
    }

    /**
     * Sets interpolator *
     *
     * @param interpolator interpolator
     */
    public void setInterpolator(Interpolator interpolator) {
        this.mInterpolator = interpolator;
    }

    /**
     * Gets outset *
     *
     * @return the outset
     */
    public int getOutset() {
        return mOutset;
    }

    /**
     * Sets outset *
     *
     * @param outset outset
     */
    public void setOutset(int outset) {
        this.mOutset = outset;
    }

    /**
     * Sets outset fraction *
     *
     * @param outsetFraction outset fraction
     */
    public void setOutsetFraction(float outsetFraction) {
        this.mOutsetFraction = outsetFraction;
    }

    @Override
    public void transformPage(Component page, float transformPos, int position, int currentPosition) {
        page.setTranslationX(0);
        if (Math.abs(transformPos - 0) < 1e-6f || Math.abs(transformPos + 1) < 1e-6f || Math.abs(transformPos - 1) < 1e-6f || Math.abs(transformPos + 2) < 1e-6f) {
            return;
        }

        switch (mMode) {
            case LEFT_OVERLAY:
                if (transformPos > 0) {
                    transform(page, transformPos);
                } else if (transformPos < 0) {
                    bringViewToFront(page);
                }
                break;
            case RIGHT_OVERLAY:
                if (transformPos < 0) {
                    transform(page, transformPos);
                } else if (transformPos > 0) {
                    bringViewToFront(page);
                }
                break;
            case NONE:
                break;
        }
    }

    /**
     * Bring view to front *
     *
     * @param view view
     */
    private void bringViewToFront(Component view) {
        ComponentContainer group = (ComponentContainer) view.getComponentParent();
        int index = group.getChildIndex(view);
        if (index != group.getChildCount() - 1) {
            group.moveChildToFront(view);

        }
        LogUtil.info(TAG, " bringViewToFront: ");
    }

    /**
     * Gets client width *
     *
     * @param page page
     * @return the client width
     */
    private int getClientWidth(Component page) {
        return page.getWidth() - page.getPaddingLeft() - page.getPaddingRight();
    }

    /**
     * Transform *
     *
     * @param page     page
     * @param position position
     */
    private void transform(Component page, float position) {
        float interpolatorPosition;
        float translationX;
        int pageWidth = getClientWidth(page);
        if (mOutset <= 0) {
            mOutset = (int) (mOutsetFraction * getClientWidth(page));
        }

        if (position < 0) {
            interpolatorPosition = mInterpolator.getInterpolation(Math.abs(position));
            translationX = -evaluate(interpolatorPosition, 0, (pageWidth - mOutset));
        } else {
            interpolatorPosition = mInterpolator.getInterpolation(position);
            translationX = evaluate(interpolatorPosition, 0, (pageWidth - mOutset));
        }
        translationX += -getClientWidth(page) * position;
        LogUtil.info(TAG, " translationX: " + translationX + " -page.getWidth(): " + -page.getWidth() + " position: " + position + " getClientWidth(page): " + getClientWidth(page));
        page.setTranslationX(translationX);
    }

    /**
     * Evaluate float
     *
     * @param fraction   fraction
     * @param startValue start value
     * @param endValue   end value
     * @return the float
     */
    private Float evaluate(float fraction, Number startValue, Number endValue) {
        float startFloat = startValue.floatValue();
        return startFloat + fraction * (endValue.floatValue() - startFloat);
    }
}